 package org.example.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.example.service.ServiceDemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
 public class DemoController {
    
    @Autowired
    private ServiceDemo serviceDemo;
    
    @Value("#{'${test.list:1,2}'.split(',')}")
    private List<Integer> list;
    
    @GetMapping("/contro1")
    public String contro1() {
            Entry entry = null;
            // 资源名
            String resourceName = "contro1";
            try {
                // entry可以理解成入口登记
                entry = SphU.entry(resourceName);
                serviceDemo.service1();
                // 被保护的逻辑, 这里为订单查询接口
                return "contro1 OK";
            } catch (BlockException blockException) {
                // 接口被限流的时候, 会进入到这里
                log.warn("---getOrder1接口被限流了---, exception: ", blockException);
                return "接口限流, 返回空";
            } finally {
                // SphU.entry(xxx) 需要与 entry.exit() 成对出现,否则会导致调用链记录异常
                if (entry != null) {
                    entry.exit();
                }
            }
    }
    @GetMapping("/contro2")
    @SentinelResource(value="contro2",blockHandler = "exceptionHandler")
    public String contro2() {
        serviceDemo.service2("contro2");
        return "OK";
    }
    
    @GetMapping("/contro3")
    @SentinelResource(value="contro3",blockHandler = "exceptionHandler")
    public String contro3() {
        return JSONObject.toJSONString(serviceDemo.service3());
    }
    
    public String exceptionHandler(BlockException e) {
        e.printStackTrace();
        return "被限流";
    }
    
    @PostConstruct
    public void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource("contro1");
        // QPS控制在2以内
        rule1.setCount(2);
        // QPS限流
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule1.setLimitApp("default");
        rules.add(rule1);
        
        FlowRule rule2 = new FlowRule();
        rule2.setResource("contro2");
        // QPS控制在2以内
        rule2.setCount(1);
        // QPS限流
        rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule2.setLimitApp("default");
        rules.add(rule2);
        
        FlowRule rule3 = new FlowRule();
        rule3.setResource("contro3");
        // QPS控制在2以内
        rule3.setCount(1);
        // QPS限流
        rule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule3.setLimitApp("default");
        rules.add(rule3);
        FlowRuleManager.loadRules(rules);
    }
}
